function myNew(fn, ...args) {
  // 创建一个对象
  const obj = Object.create(fn.prototype);
  const result = fn.call(obj, ...args);
  return Object.toString.call(result) === "[object Object]" ? result : obj;
}

// reduce实现数组扁平化
function flat(target) {
  return target.reduce((total, curr) => {
    return curr instanceof Array ? [...total, ...flat(curr)] : [...total, curr];
  }, []);
}

const arr = [1, 2, [3, 4, 5, [6, 7]], 8, [9, 10]];
const arr2 = flat(arr);

// 老生常谈冒泡

function mySort(arr) {
  const result = [...arr];
  const len = arr.length;

  for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - 1; j++) {
      if (result[j] > result[j + 1]) {
        const temp = result[j];
        result[j] = result[j + 1];
        result[j + 1] = temp;
      }
    }
  }
  return result;
}

const ss = [4, 1, 3, 2, 6, 5];
mySort(ss);

//  数组转换成树结构
function convert(
  list = [
    { id: 1, name: "部门A", parentId: 0 },
    { id: 2, name: "部门B", parentId: 0 },
    { id: 3, name: "部门C", parentId: 1 },
    { id: 4, name: "部门D", parentId: 1 },
    { id: 5, name: "部门E", parentId: 2 },
    { id: 6, name: "部门F", parentId: 3 },
    { id: 7, name: "部门G", parentId: 2 },
    { id: 8, name: "部门H", parentId: 4 },
  ],
  parentId = 0
) {
  let result = [];
  let temp = [...list];

  for (let index = 0; index < temp.length; index++) {
    const element = temp[index];
    let hasChild = temp.find(
      (t) =>
        t.parentId === element.id &&
        t.id !== element.id &&
        element.parentId === parentId
    );

    if (hasChild) {
      const newList = temp.filter((t) => {
        return t.parentId !== parentId;
      });

      element.children = convert(newList, element.id);

      result.push(element);
    } else if (element.parentId === parentId) {
      result.push(element);
    }
  }
  return result;
}

// 找数据链里的父id
function findPid(
  list = [
    {
      id: 1,
      name: "广东省",
      children: [
        {
          id: 11,
          name: "广州市",
        },
        {
          id: 12,
          name: "深圳",
          children: [
            {
              id: 121,
              name: "南山区",
            },
          ],
        },
      ],
    },
  ],
  id = 121
) {
  const stack = [...list];
  // 先找到第一个父节点
  while (stack.length) {
    const curr = stack.shift();
    if (curr.children instanceof Array) {
      const newTask = curr.children.map((child) => ({
        ...child,
        path: (curr.path || curr.id) + "-" + child.id,
      }));
      stack.concat([...newTask]);
    }
    if (curr.id === id) {
      return curr;
    }
  }
  return "no";
}

function proxyTest(object, log, setfunction) {
  return new Proxy(object, {
    get: (target, property, reciver) => {
      typeof log === "function" && log(target, property);
      return Reflect.get(target, property, reciver);
    },
    set: (target, property, value, reciver) => {
      typeof setfunction === "function" && setfunction(target, property, value);
      return Reflect.set(target, property, value, reciver);
    },
  });
}
const obj = { a: 1, b: 2 };
const tt = proxyTest(
  obj,
  (target, key) => {
    console.log(`获取target.${key} : ${target[key]}`);
  },
  (target, key, value) => {
    console.log(`设置target.${key}新value : ${value}`);
  }
);

// 用generator模拟async await
function genAsync(genFn) {
  return function () {
    const gen = genFn.call(this, arguments);
    function go(method, val) {
      return new Promise((resolve, reject) => {
        let res;
        try {
          res = gen[method](val);
        } catch (err) {
          reject(err);
        }
        const { done, value } = res;

        if (done) {
          return resolve(value);
        } else {
          return Promise.resolve(value)
            .then((res2) => {
              gen("next", res);
            })
            .catch((err) => {
              gen("throw", err);
            });
        }
      });
    }
    go("next");
  };
}

function myCall(context = window) {
  const otherArgs = arguments.slice(1);

  const symbol = new Symbol();
  context[symbol] = this;

  const val = context[symbol](...otherArgs);
  delete context[symbol];
  return val;
}

function myCall(context = window) {
  const otherArgs = arguments.slice(1);
  const symbol = new Symbol();
  context[symbol] = this;

  const val = context[symbol];
  delete context[symbol];
  return val;
}

function myBind(context) {
  const otherArgs = arguments.slice(1);
  return function F() {
    const innerArgs = arguments.slicec(1);

    return this.apply(context, [...innerArgs, ...otherArgs]);
  };
}

function AJAX(url, method, data) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.onreadystatechange = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        resolve({ data: JSON.stringify(xhr.responseText) });
      } else if (xhr.readyState === 4 && xhr.status !== 200) {
        reject("请求失败");
      }
    };
    xhr.send(data);
  });
}
